package gestoremulte.pack;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.KeyStore;
import java.util.ArrayList;

import javax.net.ssl.HostnameVerifier;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;
/*
 * Si occupa della comunicazione asincrona per l'invio dei verbali e delle notifiche
 */
public class WebServiceComunication extends AsyncTask<String, Integer, String> {
	 
    public static final int POST_TASK = 1;
    public static final int POST_JSON_NOTIFICA = 3;
    public static final int GET_TASK = 2;
    public static final int POST_VERBALE = 4;

    private int tsFE;
    private int tsBE;
    private int delayNet;
    
    private Notifica notifica;
    private Verbale verbale;
    private boolean esitoComunicazione = false;
    

    private static final String TAG = "WebServiceComunication";

    // timeout in millisecondi (aspetta per la connessione)

    // timeout in millisecondi della socket (aspetta per i dati)

    //imposta valori standard
    private int taskType = GET_TASK;
    private Context mContext = null;
    private String messaggioProcessamento = "Processing...";
    
    private ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();

    private ProgressDialog pDlg = null;

    public WebServiceComunication(int taskType, Context mContext, String processMessage) {

    	
        this.taskType = taskType;
        this.mContext = mContext;
        this.messaggioProcessamento = processMessage;
    }

    public void addNameValuePair(String name, String value) {

        params.add(new BasicNameValuePair(name, value));
    }

    private void showProgressDialog() {

        pDlg = new ProgressDialog(mContext);
        pDlg.setMessage(messaggioProcessamento);
        pDlg.setProgressDrawable(mContext.getWallpaper());
        pDlg.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        pDlg.setCancelable(false);
        pDlg.show();

    }

    @Override
    protected void onPreExecute() {

        
        showProgressDialog();

    }

    protected String doInBackground(String... urls) {

        String url = urls[0];
        String result = "";

        HttpResponse response = doResponse(url);

        if (response == null) {
            return "Comunicazione non riuscita";
        } else {

            try {

            	if(response.getStatusLine().getStatusCode()!=200){
            		Log.d("risultato comunicazione", ""+response.getStatusLine().getStatusCode());
            		result = "Comunicazione non riuscita";
            	}
            	else
            		result = inputStreamToString(response.getEntity().getContent());

            } catch (IllegalStateException e) {
                Log.e(TAG, e.getLocalizedMessage(), e);

            } catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

        }
        return result;
    }

    @Override
    protected void onPostExecute(String response) {

        //handleResponse(response);
    	Log.e("PROVA", "entato2");
    	if (response!=null){
	    	if (taskType == POST_JSON_NOTIFICA || taskType == POST_VERBALE ){
		    	
		    		if (response.equals("Comunicazione non riuscita")){
		    			Toast toast2 =Toast.makeText(mContext, response,Toast.LENGTH_LONG);
			    		toast2.show();
		    		}
		    		else{
		    			JSONObject object = null;
			    		try {
			    			
			    			object = (JSONObject) new JSONTokener(response).nextValue();
							int esito_operazione = object.getInt("esito_operazione");
							String codice_errore = object.getString("codice_errore");
							String messaggio_errore = object.getString("info");
							Log.e("PROVA", "entato");
							if (esito_operazione == 200){
								esitoComunicazione = true;
								Log.e("PROVA", "entato3");
								Toast toast =Toast.makeText(mContext, "operazione andata a buon fine",Toast.LENGTH_LONG);
								
								toast.show();
								
								tsFE = object.getInt("tsFE");
								tsBE = object.getInt("tsBE");
								
								delayNet -= (tsFE+tsBE);
								Log.e("DELAYNet",""+delayNet );
								Log.e("tsFE",""+tsFE );
								Log.e("tsBE",""+tsBE );
							}
							else{
								Toast toast =Toast.makeText(mContext,"Errore: " + codice_errore + "- " + messaggio_errore,Toast.LENGTH_LONG);
						    	toast.show();
						    	esitoComunicazione = false;
							}
							
						} catch (JSONException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
							esitoComunicazione = false;
						}	
		    		}
			        pDlg.dismiss();
	    	}
	    	
    	}
    }
   
    private HttpResponse doResponse(String url) {

    	//Looper.prepare(); 
        // Use our connection and data timeouts as parameters for our
        // DefaultHttpClient
        HttpClient httpclient = getNewHttpClient();

        HttpResponse response = null;

        try {
            switch (taskType) {

            case POST_TASK:
                HttpPost httppost = new HttpPost(url);
                // Add parameters
                httppost.setEntity(new UrlEncodedFormEntity(params));

                response = httpclient.execute(httppost);
                break;
            case GET_TASK:
                HttpGet httpget = new HttpGet(url);
                response = httpclient.execute(httpget);
                break;
                
                
            case POST_JSON_NOTIFICA:
           	 
           	 JSONObject json = new JSONObject();
           	 json.put("nverbale", notifica.getVerbaleNumber());
           	 json.put("data_ora", notifica.getDataOra());
           	 json.put("via_comune", notifica.getViaComune());
           	 json.put("sanzione", notifica.getSanzione());
           	 json.put("infrazioni", new JSONArray(notifica.getInfrazioni()));
           	 json.put("descrizioneInfrazioni", new JSONArray(notifica.getDescrizioneInfrazione()));
           	 json.put("targa", notifica.getTarga());
           	 json.put("lat", notifica.getLat());
           	 json.put("longi", notifica.getLon());
           	 
           	 if (VariabiliCondiviseApplication.fotoScattata)
           		 json.put("foto", notifica.getPhoto());
           	 else
           		json.put("foto", "");
           	 
           	 json.put("matricola_agente", notifica.getMatricolaAgente());
           	 json.put("codice_agente", notifica.getCodice());
           	 json.put("IMEI", notifica.getIMEI());
           	 
           	 StringEntity entity = new StringEntity( json.toString());  
           	
            	
           	 HttpPost httppost2 = new HttpPost(url);
           
             entity.setContentType("application/json;charset=UTF-8");
           //  entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,"application/json;charset=UTF-8"));
             httppost2.setEntity(entity);
             
             delayNet = (int) System.currentTimeMillis();
           	 response = httpclient.execute(httppost2);
           	 delayNet = (int) (System.currentTimeMillis() - delayNet);
           	 
           	 break;
           	 
            case POST_VERBALE:
            	JSONObject jsonVerbale = new JSONObject();
            	jsonVerbale.put("nverbale", verbale.getNumeroVerbale());
            	jsonVerbale.put("data_ora", verbale.getData_ora());
            	jsonVerbale.put("luogoTrasgressione", verbale.getLuogoTrasgressione());
            	jsonVerbale.put("sottoscritti", verbale.getSottoscritti());
            	jsonVerbale.put("nome_cognome_trasgressore", verbale.getNome_cognome_trasgressore());
            	jsonVerbale.put("NascitaTrasgressore", verbale.getNascitaTrasgressore());
            	jsonVerbale.put("ProvNascitaTrasgr", verbale.getProvNascitaTrasgr());
            	jsonVerbale.put("DataNascitaTrasgr", verbale.getDataNascitaTrasgr());
            	jsonVerbale.put("residenzaTrasgr", verbale.getResidenzaTrasgr());
            	jsonVerbale.put("provResidenzaTrasgr", verbale.getProvResidenzaTrasgr());
            	jsonVerbale.put("documento", verbale.getDocumento());
            	jsonVerbale.put("nDocTrasgr", verbale.getnDocTrasgr());
            	jsonVerbale.put("documentoRilasciatoData", verbale.getDocumentoRilasciatoData());
            	jsonVerbale.put("documentoRilasciatoDa", verbale.getDocumentoRilasciatoDa());
            	jsonVerbale.put("veicolo", verbale.getVeicolo());
            	jsonVerbale.put("targa", verbale.getTarga());
            	jsonVerbale.put("nome_cognome_possessore", verbale.getNome_cognome_possessore());
            	jsonVerbale.put("NascitaPossessore", verbale.getNascitaPossessore());
            	jsonVerbale.put("ProvNascitaPoss", verbale.getProvNascitaPoss());
            	jsonVerbale.put("DataNascitaPoss", verbale.getDataNascitaPoss());
            	jsonVerbale.put("residenzaPoss", verbale.getResidenzaPoss());
            	jsonVerbale.put("provResidenzaPoss", verbale.getProvResidenzaPoss());
            	jsonVerbale.put("violazioni", verbale.getViolazioni());
            	jsonVerbale.put("dichiara", verbale.getDichiara());
            	jsonVerbale.put("sanzione", verbale.getSanzione());
            	jsonVerbale.put("matricola_agente",verbale.getMatrAg() );
            	jsonVerbale.put("codice_agente", verbale.getCodice());
            	jsonVerbale.put("IMEI",verbale.getIMEI() );
            	jsonVerbale.put("lat", verbale.getLat());
            	jsonVerbale.put("longi", verbale.getLon());
            	
            	 if (VariabiliCondiviseApplication.fotoScattata)
            		 jsonVerbale.put("foto", verbale.getPhoto());
               	 else
               		jsonVerbale.put("foto", "");
            	
            	
            	
	        	StringEntity entityVerbale = new StringEntity( jsonVerbale.toString());  
	           	HttpPost httppost3 = new HttpPost(url);
	           
	           	entityVerbale.setContentType("application/json;charset=UTF-8");
	           //	entityVerbale.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,"application/json;charset=UTF-8"));
	           	httppost3.setEntity(entityVerbale);
	           	
	           	delayNet = (int) System.currentTimeMillis();
	           	response = httpclient.execute(httppost3);
	           	delayNet = (int) (System.currentTimeMillis() - delayNet);
	           	
	           	break;
         	
            }
        } catch (Exception e) {

        	Log.e(TAG, e.getLocalizedMessage(), e);
        	
           // pDlg.dismiss();
           /* Toast toast =Toast.makeText(mContext, "Impossibile comunicare... richiesta fallitta",Toast.LENGTH_LONG);
        	toast.show();
        //	 Looper.loop();*/
            return null;

        }

      // Looper.loop();
        return response;
    }
    
   

    private String inputStreamToString(InputStream is) {

        String line = "";
        StringBuilder total = new StringBuilder();

        // Wrap a BufferedReader around the InputStream
        BufferedReader rd = new BufferedReader(new InputStreamReader(is));

        try {
            // Read response until the end
            while ((line = rd.readLine()) != null) {
                total.append(line);
            }
        } catch (IOException e) {
            Log.e(TAG, e.getLocalizedMessage(), e);
        }

        // Return full string
        return total.toString();
    }
    
    public void setNotifica(Notifica i){
    	notifica = i;
    }
    
    public void setVerbale(Verbale i){
    	verbale = i;
    }


	public boolean isEsitoComunicazione() {
		return esitoComunicazione;
	}


	
	private HttpClient getNewHttpClient() {
	    try {
	    	
	    	HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
	        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
	        trustStore.load(null, null);

	        MySSLSocketFactory sf = new MySSLSocketFactory(trustStore);
	        sf.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);

	        HttpParams params = new BasicHttpParams();
	        HttpConnectionParams.setConnectionTimeout(params, 30000);
	        HttpConnectionParams.setSoTimeout(params, 30000);

	        SchemeRegistry registry = new SchemeRegistry();
	        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
	        registry.register(new Scheme("https", sf, 443));

	        ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

	        return new DefaultHttpClient(ccm, params);
	    } catch (Exception e) {
	        return new DefaultHttpClient();
	    }
	}
    

}